package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.check.CheckResult;
import com.bsg.upm.check.UnitCheck;
import com.bsg.upm.constant.DictConstants;
import com.bsg.upm.constant.DictTypeConstants;
import com.bsg.upm.constant.OperateDictConstants;
import com.bsg.upm.constant.OperateDictTypeConstants;
import com.bsg.upm.constant.SubTaskDictConstants;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.constant.TaskDictConstants;
import com.bsg.upm.constant.TaskDictTypeConstants;
import com.bsg.upm.dto.SlowLogDetailDto;
import com.bsg.upm.dto.SlowLogDto;
import com.bsg.upm.dto.UnitDto;
import com.bsg.upm.entity.ClusterEntity;
import com.bsg.upm.entity.DefinitionSubTaskConfigEntity;
import com.bsg.upm.entity.HostEntity;
import com.bsg.upm.entity.OperateLogEntity;
import com.bsg.upm.entity.ServEntity;
import com.bsg.upm.entity.SiteEntity;
import com.bsg.upm.entity.SubServEntity;
import com.bsg.upm.entity.SubServSoftwareImageEntity;
import com.bsg.upm.entity.SubTaskEntity;
import com.bsg.upm.entity.TaskEntity;
import com.bsg.upm.entity.UnitEntity;
import com.bsg.upm.entity.UserEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.HttpClientUtils;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;
import com.bsg.upm.util.DateUtils;
import com.bsg.upm.util.PrimaryKeyUtils;

/**
 * 服务单元管理业务处理类
 * 
 * @author HCK
 *
 */
@Service
public class UnitService extends BaseService {

	@Resource
	private UnitCheck unitCheck;

	/**
	 * 获取单元列表
	 * 
	 * @param servId
	 *            服务编码
	 * @param subServType
	 *            子服务类型
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson list(String servId, String subServType) throws APIException {
		try {
			// 结果集
			JSONArray results = new JSONArray();

			// 获取指定的服务
			ServEntity serv = servDao.get(servId);
			if (serv == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "服务不存在");
			}

			// 站点
			SiteEntity site = serv.getOrder().getArea().getSite();

			// 服务的拓扑信息
			JSONObject topologyInfo = null;
			try {
				topologyInfo = getTopology(serv);
			} catch (Exception e) {
			}

			// 符合条件的子服务
			List<SubServEntity> subServs = match(serv.getSubServs(), subServType);
			for (SubServEntity subServ : subServs) {
				// MGM服务信息
				JSONObject mgmServInfo = null;
				if (StringUtils.isNoneBlank(subServ.getRelateId())) {
					mgmServInfo = getServInfoFromMGM(site.getId(), subServ.getRelateId());
				}

				// HORUS监控信息
				JSONArray monitorUnitInfos = null;
				String dfSubServType = subServ.getSubOrder().getDefinitionSubServ().getName();
				String metric = definitionMetricCache.getMetric(dfSubServType, "status");
				try {
					if (StringUtils.isNoneBlank(subServ.getRelateId())) {
						Map<String, JSONArray> maps = getNohistory(site.getId(), metric, subServ.getRelateId());
						monitorUnitInfos = maps.get(subServ.getRelateId());
					}
				} catch (APIException e) {
				}

				// 构建单元展示对象集合
				List<UnitDto> unitsDto = buildUnitDtos(subServ, mgmServInfo, monitorUnitInfos, topologyInfo);
				results.addAll(unitsDto);
			}
			return RespJsonFactory.buildOK(results);
		} catch (Exception e) {
			logger.error("服务单元查询异常", e);
			throw new APIException("服务单元查询异常:" + e.getMessage());
		}
	}

	/**
	 * 慢日志查询
	 * 
	 * @param unitId
	 *            单元编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson slowLog(String unitId) throws APIException {
		try {
			SlowLogDto slowLogDto = new SlowLogDto();
			
			// 获取指定单元信息
			UnitEntity unit = unitDao.get(unitId);

			if (StringUtils.isNotBlank(unit.getRelateId())) {

				JSONObject paramJson = new JSONObject();
				paramJson.put("nameOrID", unit.getRelateId());

				JSONArray cmdJsonArr = new JSONArray();
				paramJson.put("cmd", cmdJsonArr);

				cmdJsonArr.add("/root/pt-slowlog.sh");

				String siteId = unit.getSubServ().getServ().getOrder().getArea().getSite().getId();
				
				if (StringUtils.isNotBlank(unit.getSubServ().getRelateId())) {
					String slowLog = executeMgmExec(siteId, unit.getSubServ().getRelateId(), paramJson.toJSONString());
					if (StringUtils.isNotBlank(slowLog)) {
						JSONObject slowInfo = JSONObject.parseObject(slowLog);
						
						JSONObject globalInfo = slowInfo.getJSONObject("global");
						if (globalInfo != null) {
							slowLogDto.setQuerySum(globalInfo.getLongValue("query_count"));
							slowLogDto.setUniqueQuerySum(globalInfo.getLongValue("unique_query_count"));
							JSONArray fileInfos = globalInfo.getJSONArray("files");
							if (fileInfos != null && fileInfos.size() > 0) {
								slowLogDto.setSize(fileInfos.getJSONObject(0).getLongValue("size"));
							}
						}
						
						JSONArray classInfos = slowInfo.getJSONArray("classes");
						if (classInfos != null) {
							List<SlowLogDetailDto> detailDtos = new ArrayList<>(classInfos.size());
							slowLogDto.setSlowLogDetails(detailDtos);
							for (int i = 0; i < classInfos.size(); i++) {
								SlowLogDetailDto detailDto = new SlowLogDetailDto();
								detailDtos.add(detailDto);
								
								JSONObject classInfo = classInfos.getJSONObject(i);
								detailDto.setCheckSum(classInfo.getString("checksum"));
								detailDto.setQuerySql(classInfo.getString("fingerprint"));
								detailDto.setCount(classInfo.getLongValue("query_count"));
								detailDto.setFirstSceen(DateUtils.dateTimeToString(DateUtils.parseGoDate(classInfo.getString("ts_min"))));
								detailDto.setLastSceen(DateUtils.dateTimeToString(DateUtils.parseGoDate(classInfo.getString("ts_max"))));
								
								JSONObject metricsInfo = classInfo.getJSONObject("metrics");
								if (metricsInfo != null) {
									JSONObject queryTimeInfo = metricsInfo.getJSONObject("Query_time");
									if (queryTimeInfo != null) {
										detailDto.setAvg(queryTimeInfo.getDoubleValue("avg"));
										detailDto.setMax(queryTimeInfo.getDoubleValue("max"));
										detailDto.setMin(queryTimeInfo.getDoubleValue("min"));
										detailDto.setTotal(queryTimeInfo.getDoubleValue("sum"));
									}
									
									JSONObject dbInfo = metricsInfo.getJSONObject("db");
									if (dbInfo != null) {
										detailDto.setDatabse(dbInfo.getString("value"));
									}
									
									JSONObject hostInfo = metricsInfo.getJSONObject("host");
									if (hostInfo != null) {
										detailDto.setHost(hostInfo.getString("value"));
									}
									
									JSONObject userInfo = metricsInfo.getJSONObject("user");
									if (userInfo != null) {
										detailDto.setUser(userInfo.getString("value"));
									}
								}
							}
						}
					}
				}
			}
			return RespJsonFactory.buildOK(slowLogDto);
		} catch (Exception e) {
			logger.error("慢日志查询异常", e);
			throw new APIException("慢日志查询异常:" + e.getMessage());
		}
	}

	/**
	 * 单元启动
	 * 
	 * @param unitId
	 *            单元编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson start(String unitId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_START;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定单元信息
			UnitEntity unit = unitDao.get(unitId);

			// 单元启动检查
			CheckResult chkRS = unitCheck.checkStart(unit);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元启动任务
			TaskEntity task = buildStartUnitTask(unit, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元停止
	 * 
	 * @param unitId
	 *            单元编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson stop(String unitId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_STOP;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定单元信息
			UnitEntity unit = unitDao.get(unitId);

			// 单元停止检查
			CheckResult chkRS = unitCheck.checkStop(unit);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元停止任务
			TaskEntity task = buildStopUnitTask(unit, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元备份
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson backup(Map<String, Object> paramMap) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_BACKUP;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 单元编码
			String unitId = (String) paramMap.get("unitId");
			// 获取指定的单元
			UnitEntity unit = unitDao.get(unitId);

			// 单元备份检查
			CheckResult chkRS = unitCheck.checkBackup(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元备份任务
			TaskEntity task = buildBackupUnitTask(unit, paramMap, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元还原
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson restore(Map<String, Object> paramMap) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_RESTORE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 单元编码
			String unitId = (String) paramMap.get("unitId");
			// 获取指定的单元
			UnitEntity unit = unitDao.get(unitId);

			// 单元还原检查
			CheckResult chkRS = unitCheck.checkRestore(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			String siteId = unit.getSubServ().getServ().getOrder().getArea().getSite().getId();
			String mgmBackupFileId = (String) paramMap.get("backupFileId");
			JSONObject mgmBackupFileInfo = getBackupFileInfoFromMGM(siteId, mgmBackupFileId);
			String filePath = mgmBackupFileInfo.getString("path");

			// 构建单元还原任务
			TaskEntity task = buildRestoreUnitTask(unit, filePath, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元迁移
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson migrate(Map<String, Object> paramMap) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_MIGRATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 单元编码
			String unitId = (String) paramMap.get("unitId");
			// 获取指定的单元
			UnitEntity unit = unitDao.get(unitId);

			// 单元迁移检查
			CheckResult chkRS = unitCheck.checkMigrate(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元迁移任务
			TaskEntity task = buildMigrateUnitTask(unit, paramMap, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元重建
	 * 
	 * @param paramMap
	 *            请求参数
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson rebuild(Map<String, Object> paramMap) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_REBUILD;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 单元编码
			String unitId = (String) paramMap.get("unitId");
			// 获取指定的单元
			UnitEntity unit = unitDao.get(unitId);

			// 单元重建检查
			CheckResult chkRS = unitCheck.checkRebuild(paramMap);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元重建任务
			TaskEntity task = buildRebuildUnitTask(unit, paramMap, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元隔离
	 * 
	 * @param unitId
	 *            单元编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson isolate(String unitId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_ISOLATE;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定单元信息
			UnitEntity unit = unitDao.get(unitId);

			// 单元隔离检查
			CheckResult chkRS = unitCheck.checkIsolate(unit);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元隔离任务
			TaskEntity task = buildIsolateUnitTask(unit, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 单元回切
	 * 
	 * @param unitId
	 *            单元编码
	 * @return RespJson请求结果对象
	 * @throws APIException
	 *             API异常处理类
	 */
	public RespJson recover(String unitId) throws APIException {
		// 事务定义
		DefaultTransactionDefinition def = null;
		// 事务状态
		TransactionStatus txStatus = null;

		// 操作动作
		String operateAcion = OperateDictConstants.ACTION_RECOVER;
		String operateAcionText = dictTypeCache.getTextFromCache(OperateDictTypeConstants.OPERATE_ACTION, operateAcion);
		try {
			// 获取指定单元信息
			UnitEntity unit = unitDao.get(unitId);

			// 单元回切检查
			CheckResult chkRS = unitCheck.checkRecover(unit);
			if (chkRS.isError()) {
				return RespJsonFactory.build(chkRS.getStatus(), chkRS.getErrorMsg());
			}

			def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
			txStatus = txManager.getTransaction(def);

			// 保存操作日志
			OperateLogEntity operateLog = saveOperateLog(OperateDictConstants.MODEL_UNIT, operateAcion, unit.getId(),
					unit.getRelateName());

			// 构建单元回切任务
			TaskEntity task = buildRecoverUnitTask(unit, operateLog);
			saveTask(task);
			txManager.commit(txStatus);

			startTask(task);

			return RespJsonFactory.buildOK();
		} catch (Exception e) {
			if (txStatus != null) {
				txManager.rollback(txStatus);
			}
			logger.error("单元" + operateAcionText + "异常", e);
			throw new APIException("单元" + operateAcionText + "异常" + e.getMessage());
		}
	}

	/**
	 * 构建单元展示对象集合
	 * 
	 * @param subServ
	 *            子服务对象
	 * @param mgmServInfo
	 *            MGM服务信息
	 * @param monitorUnitInfos
	 *            HORUS单元监控信息
	 * @param topologyInfo
	 *            拓扑信息
	 * @return 单元展示对象集合
	 */
	public List<UnitDto> buildUnitDtos(SubServEntity subServ, JSONObject mgmServInfo, JSONArray monitorUnitInfos,
			JSONObject topologyInfo) {
		List<UnitEntity> units = subServ.getUnits();
		List<UnitDto> unitsDto = new ArrayList<>(units.size());
		for (UnitEntity unit : units) {
			// 构建单元基本信息
			UnitDto unitDto = buildBaseShowDto(unit);
			unitsDto.add(unitDto);

			SiteEntity site = subServ.getServ().getOrder().getArea().getSite();
			unitDto.setSiteId(site.getId());
			unitDto.setSiteName(site.getName());
			unitDto.setPortValue(subServ.getPort().getPortValue());
			unitDto.setType(subServ.getSubOrder().getDefinitionSubServ().getName());

			if (mgmServInfo != null) {
				JSONArray mgmUnitInfos = mgmServInfo.getJSONArray("units");
				JSONObject mgmUnitInfo = findUnitInfoFromMGM(mgmUnitInfos, unit.getRelateId());
				setMgmUnitShow(unitDto, mgmUnitInfo);
			}

			JSONObject monitorUnitInfo = findMonitorUnitInfo(monitorUnitInfos, unit.getRelateId());
			setMonitorUnitShow(unitDto, monitorUnitInfo);

			String availableStatus = DictConstants.UNIT_STATUS_UNKNOWN;
			if (topologyInfo != null) {
				String defitionServCode = subServ.getServ().getOrder().getDefinitionServ().getCode();
				if (SysConstants.SERV_UPSQL_UPPROXY_SWM_CODE.equals(defitionServCode)) {
					JSONObject datanodeGroupInfo = topologyInfo.getJSONObject("datanode_group");
					if (datanodeGroupInfo != null) {
						JSONObject swmServInfo = datanodeGroupInfo.getJSONObject(subServ.getRelateId());
						if (swmServInfo != null) {
							JSONObject swmUnitInfo = swmServInfo.getJSONObject(unitDto.getRelateName());
							if (swmUnitInfo != null) {
								unitDto.setRole(swmUnitInfo.getString("type"));
								availableStatus = swmUnitInfo.getString("status");
							}
						}
					}
				} else if (SysConstants.SERV_UPREDIS_URPROXY_SENTINEL_CODE.equals(defitionServCode)) {
					JSONArray roleInfos = topologyInfo.getJSONArray(subServ.getRelateId());
					if (roleInfos != null) {
						for (int i = 0; i < roleInfos.size(); i++) {
							unitDto.setRole(roleInfos.getJSONObject(i).getString("value"));
						}
					}
				}
			}
			unitDto.setAvailableStatus(availableStatus);
		}
		return unitsDto;
	}

	/**
	 * 构建单元基本信息展示对象
	 * 
	 * @param unit
	 *            单元对象
	 * @return 单元基本信息对象
	 */
	private UnitDto buildBaseShowDto(UnitEntity unit) {
		UnitDto unitDto = new UnitDto();
		unitDto.setId(unit.getId());
		unitDto.setRelateId(unit.getRelateId());
		unitDto.setRelateName(unit.getRelateName());
		List<TaskEntity> tasks = unit.getTasks();
		if (tasks != null && tasks.size() > 0) {
			unitDto.setTaskStatus(tasks.get(0).getStatus());
			unitDto.setTaskStatusText(
					dictTypeCache.getTextFromCache(TaskDictTypeConstants.TASK_STATUS, unitDto.getTaskStatus()));
		}
		return unitDto;
	}

	/**
	 * MGM单元展示
	 * 
	 * @param unitDto
	 *            单元展示对象
	 * @param mgmUnitInfo
	 *            mgm单元信息
	 */
	private void setMgmUnitShow(UnitDto unitDto, JSONObject mgmUnitInfo) {
		if (mgmUnitInfo != null) {
			JSONObject engineInfo = mgmUnitInfo.getJSONObject("engine");
			if (engineInfo != null) {
				String hostRelateId = engineInfo.getString("node");
				if (StringUtils.isNotBlank(hostRelateId)) {
					HostEntity host = hostDao.getByRelateId(hostRelateId);
					ClusterEntity cluster = host.getCluster();
					// 集群
					unitDto.setClusterId(cluster.getId());
					unitDto.setClusterName(cluster.getName());
					// 主机
					unitDto.setHostId(host.getId());
					unitDto.setHostName(host.getName());
					// 主机IP
					unitDto.setHostIp(host.getSshIp());
				}
			}

			JSONArray networkingInfos = mgmUnitInfo.getJSONArray("networkings");
			if (networkingInfos != null && networkingInfos.size() > 0) {
				JSONObject networkingInfo = networkingInfos.getJSONObject(0);
				String serverIp = networkingInfo.getString("ip_addr") + "/" + networkingInfo.getIntValue("prefix");
				// 服务IP
				unitDto.setServerIp(serverIp);
			}

			JSONObject containerConfigInfo = mgmUnitInfo.getJSONObject("container_config");
			if (containerConfigInfo != null) {
				JSONObject hostConfigInfo = containerConfigInfo.getJSONObject("HostConfig");
				if (hostConfigInfo != null) {
					String cpusetCpus = hostConfigInfo.getString("CpusetCpus");
					// CPU数量
					unitDto.setCpuCount(cpusetCpus.split(",").length);
					// 内存容量
					unitDto.setMemSize(hostConfigInfo.getLongValue("Memory"));
				}
			}

			JSONArray volumeInfos = mgmUnitInfo.getJSONArray("volumes");
			if (volumeInfos != null) {
				for (int k = 0; k < volumeInfos.size(); k++) {
					JSONObject volumeInfo = volumeInfos.getJSONObject(k);
					if (volumeInfo.getString("type").equals("DAT")) {
						// 数据目录容量
						unitDto.setDataDirSize(volumeInfo.getLongValue("size"));
					} else if (volumeInfo.getString("type").equals("LOG")) {
						// 日志目录容量
						unitDto.setLogDirSize(volumeInfo.getLongValue("size"));
					}
				}
			}

			JSONObject containerInfo = mgmUnitInfo.getJSONObject("container");
			if (containerInfo != null) {
				// 容器状态
				unitDto.setContainerStatus(containerInfo.getString("Status"));

				JSONObject labelsInfo = containerInfo.getJSONObject("Labels");
				if (labelsInfo != null) {
					String mgmImageId = labelsInfo.getString("mgm.image.id");
					if (StringUtils.isNotBlank(mgmImageId)) {
						SubServSoftwareImageEntity image = subServSoftwareImageDao.getByRelateId(mgmImageId);
						if (image != null) {
							unitDto.setSoftwareVersion(getSoftwareImageNameAndVersion(image));
						}
					}

				}
			}
		}
	}

	/**
	 * 监控单元展示
	 * 
	 * @param unitDto
	 *            单元展示对象
	 * @param monitorUnitInfo
	 *            监控单元信息
	 */
	private void setMonitorUnitShow(UnitDto unitDto, JSONObject monitorUnitInfo) {
		String status = DictConstants.UNIT_STATUS_UNKNOWN;
		if (monitorUnitInfo != null) {
			if (StringUtils.isNotBlank(monitorUnitInfo.getString("value")))
				status = monitorUnitInfo.getString("value");
		}
		unitDto.setStatus(status);
		unitDto.setStatusText(dictTypeCache.getTextFromCache(DictTypeConstants.UNIT_STATUS, unitDto.getStatus()));
	}

	private JSONObject findUnitInfoFromMGM(JSONArray mgmUnitInfos, String unitId) {
		if (mgmUnitInfos == null) {
			return null;
		}
		for (int i = 0; i < mgmUnitInfos.size(); i++) {
			JSONObject mgmUnitInfo = mgmUnitInfos.getJSONObject(i);
			if (mgmUnitInfo.getJSONObject("unit").getString("id").equals(unitId)) {
				return mgmUnitInfo;
			}
		}
		return null;
	}

	private JSONObject findMonitorUnitInfo(JSONArray MonitorUnitInfos, String unitId) {
		if (MonitorUnitInfos == null) {
			return null;
		}
		for (int i = 0; i < MonitorUnitInfos.size(); i++) {
			JSONObject monitorUnitInfo = MonitorUnitInfos.getJSONObject(i);
			if (monitorUnitInfo.getString("name").equals(unitId)) {
				return monitorUnitInfo;
			}
		}
		return null;
	}

	/**
	 * 构建单元启动任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildStartUnitTask(UnitEntity unit, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_START);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_START_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildStartUnitSubTasks(unit, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元启动子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildStartUnitSubTasks(UnitEntity unit, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_START);
		subTask.setAsync(true);
		DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
				.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
		subTask.setTimeout(dfSubTaskConfig.getTimeout());
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		String url = "/" + SysConstants.MGM_VERSION + "/services/" + unit.getSubServ().getRelateId() + "/exec";
		subTask.setUrl(url);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setParam(buildStartUnitParam(unit));
		subTask.setPriority(1);
		return subTasks;
	}

	/**
	 * 构建单元启动所需参数
	 * 
	 * @param unit
	 *            单元对象
	 * @return String 单元启动所需参数
	 */
	private String buildStartUnitParam(UnitEntity unit) {
		JSONObject paramJson = new JSONObject();
		paramJson.put("nameOrID", unit.getRelateId());

		JSONArray cmdJsonArr = new JSONArray();
		paramJson.put("cmd", cmdJsonArr);

		cmdJsonArr.add("/root/serv");
		cmdJsonArr.add("start");
		return paramJson.toJSONString();
	}

	/**
	 * 构建单元停止任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildStopUnitTask(UnitEntity unit, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_STOP);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_STOP_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildStopUnitSubTasks(unit, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元停止子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildStopUnitSubTasks(UnitEntity unit, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_STOP);
		subTask.setAsync(true);
		DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
				.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
		subTask.setTimeout(dfSubTaskConfig.getTimeout());
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		String url = "/" + SysConstants.MGM_VERSION + "/services/" + unit.getSubServ().getRelateId() + "/exec";
		subTask.setUrl(url);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setParam(buildStopUnitParam(unit));
		subTask.setPriority(1);
		return subTasks;
	}

	/**
	 * 构建单元停止所需参数
	 * 
	 * @param unit
	 *            单元对象
	 * @return String 单元停止所需参数
	 */
	private String buildStopUnitParam(UnitEntity unit) {
		JSONObject paramJson = new JSONObject();
		paramJson.put("nameOrID", unit.getRelateId());

		JSONArray cmdJsonArr = new JSONArray();
		paramJson.put("cmd", cmdJsonArr);

		cmdJsonArr.add("/root/serv");
		cmdJsonArr.add("stop");
		return paramJson.toJSONString();
	}

	/**
	 * 构建单元备份任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildBackupUnitTask(UnitEntity unit, Map<String, Object> paramMap, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_BACKUP);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_BACKUP_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildBackupUnitSubTasks(unit, paramMap, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元备份子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildBackupUnitSubTasks(UnitEntity unit, Map<String, Object> paramMap, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_BACKUP);
		subTask.setAsync(true);
		DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
				.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
		subTask.setTimeout(dfSubTaskConfig.getTimeout());
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		String url = "/" + SysConstants.MGM_VERSION + "/services/" + unit.getSubServ().getRelateId() + "/backup";
		subTask.setUrl(url);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setParam(buildBackupUnitParam(unit, paramMap));
		subTask.setPriority(1);
		return subTasks;
	}

	/**
	 * 构建单元备份所需参数
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @return String 单元备份所需参数
	 */
	private String buildBackupUnitParam(UnitEntity unit, Map<String, Object> paramMap) {
		JSONObject paramJson = new JSONObject();
		paramJson.put("nameOrID", unit.getRelateId());
		String type = (String) paramMap.get("type");
		if (StringUtils.isBlank(type)) {
			type = "full";
		}
		Integer retention = (Integer) paramMap.get("retention");
		if (retention == null) {
			retention = 7;
		}
		String mgmBackupType = definitionCache.getDefinitionCodeFromCache(DictTypeConstants.BACKUP_TYPE, type);
		paramJson.put("type", mgmBackupType);
		paramJson.put("backup_files_retention", retention);
		paramJson.put("tag", unit.getSubServ().getServ().getOrder().getCreateUserLoginName());
		paramJson.put("remark", "手动备份");
		return paramJson.toJSONString();
	}

	/**
	 * 从MGM上获取指定备份文件的路径
	 * 
	 * @param siteId
	 *            站点编码
	 * @param mgmBackupFileId
	 *            备份文件编码
	 * @return JSONObject 备份文件详细
	 * @throws APIException
	 *             API异常处理类
	 */
	private JSONObject getBackupFileInfoFromMGM(String siteId, String mgmBackupFileId) throws APIException {
		String urlPattern = "/{0}/backupfiles/{1}";
		String url = MessageFormat.format(urlPattern, SysConstants.MGM_VERSION, mgmBackupFileId);
		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_MGM, url);
		if (httpRespJson.getStatus() == HttpStatus.SC_OK) {
			return ((JSONObject) httpRespJson.getData());
		} else {
			throw new APIException(httpRespJson.getMsg());
		}
	}

	/**
	 * 构建单元还原任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param filePath
	 *            文件路径名
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildRestoreUnitTask(UnitEntity unit, String filePath, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_RESTORE);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_RESTORE_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildRestoreUnitSubTasks(unit, filePath, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元还原子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param filePath
	 *            文件路径名
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildRestoreUnitSubTasks(UnitEntity unit, String filePath, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_RESTORE);
		subTask.setAsync(true);
		DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
				.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
		subTask.setTimeout(dfSubTaskConfig.getTimeout());
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		String url = "/" + SysConstants.MGM_VERSION + "/services/" + unit.getSubServ().getRelateId() + "/restore";
		subTask.setUrl(url);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setParam(buildRestoreUnitParam(unit, filePath));
		subTask.setPriority(1);
		return subTasks;
	}

	/**
	 * 构建单元还原所需参数
	 * 
	 * @param unit
	 *            单元对象
	 * @param filePath
	 *            文件路径名
	 * @return String 单元还原所需参数
	 */
	private String buildRestoreUnitParam(UnitEntity unit, String filePath) {
		JSONObject paramJson = new JSONObject();
		JSONArray unitJsonArr = new JSONArray();
		paramJson.put("units", unitJsonArr);
		unitJsonArr.add(unit.getRelateId());
		paramJson.put("file", filePath);
		return paramJson.toJSONString();
	}

	/**
	 * 构建单元迁移任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildMigrateUnitTask(UnitEntity unit, Map<String, Object> paramMap,
			OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_MIGRATE);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_MIGRATE_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildMigrateUnitSubTasks(unit, paramMap, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元迁移子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildMigrateUnitSubTasks(UnitEntity unit, Map<String, Object> paramMap, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_MIGRATE);
		subTask.setAsync(true);
		DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
				.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
		subTask.setTimeout(dfSubTaskConfig.getTimeout());
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		String url = "/" + SysConstants.MGM_VERSION + "/services/" + unit.getSubServ().getRelateId() + "/migrate";
		subTask.setUrl(url);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setParam(buildMigrateUnitParam(unit, paramMap));
		subTask.setPriority(1);

		SubTaskEntity subTask_link = new SubTaskEntity();
		subTasks.add(subTask_link);

		subTask_link.setId(PrimaryKeyUtils.uniqueId());
		subTask_link.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask_link.setObjId(unit.getId());
		subTask_link.setObjName(unit.getRelateName());
		subTask_link.setObj(unit);
		subTask_link.setActionType(SubTaskDictConstants.ACTION_TYPE_LINK);
		subTask_link.setAsync(true);
		dfSubTaskConfig = definitionSubTaskConfigCache.getDfSubTaskConfigFromCache(subTask_link.getObjType(),
				subTask_link.getActionType());
		if (dfSubTaskConfig == null) {
			subTask_link.setTimeout(0);
		} else {
			subTask_link.setTimeout(dfSubTaskConfig.getTimeout());
		}
		subTask_link.setStatus(SubTaskDictConstants.STATUS_NOTRUN);
		String linkUrl = "/" + SysConstants.MGM_VERSION + "/services/link";
		subTask_link.setUrl(linkUrl);
		subTask_link.setMethodType(HttpClientUtils.METHOD_POST);
		subTask_link.setParam(getLinkParam(unit.getSubServ().getServ(), unit.getRelateId()));
		subTask_link.setPriority(2);
		return subTasks;
	}

	/**
	 * 构建单元迁移所需参数
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @return String 单元迁移所需参数
	 */
	private String buildMigrateUnitParam(UnitEntity unit, Map<String, Object> paramMap) {
		JSONObject paramJson = new JSONObject();
		paramJson.put("nameOrID", unit.getRelateId());
		String strategy = (String) paramMap.get("strategy");
		if (DictConstants.STRATEGY_AUTO.equals(strategy)) {

		} else if (DictConstants.STRATEGY_MANUAL.equals(strategy)) {
			JSONArray candidateJsonArr = new JSONArray();
			paramJson.put("candidates", candidateJsonArr);
			String hostId = (String) paramMap.get("host");
			HostEntity host = hostDao.get(hostId);
			candidateJsonArr.add(host.getRelateId());
		}
		return paramJson.toJSONString();
	}

	/**
	 * 构建单元重建任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildRebuildUnitTask(UnitEntity unit, Map<String, Object> paramMap,
			OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_REBUILD);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_REBUILD_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildRebuildUnitSubTasks(unit, paramMap, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元重建子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildRebuildUnitSubTasks(UnitEntity unit, Map<String, Object> paramMap, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_REBUILD);
		subTask.setAsync(true);
		DefinitionSubTaskConfigEntity dfSubTaskConfig = definitionSubTaskConfigCache
				.getDfSubTaskConfigFromCache(subTask.getObjType(), subTask.getActionType());
		subTask.setTimeout(dfSubTaskConfig.getTimeout());
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		String url = "/" + SysConstants.MGM_VERSION + "/services/" + unit.getSubServ().getRelateId() + "/rebuild";
		subTask.setUrl(url);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setParam(buildRebuildUnitParam(unit, paramMap));
		subTask.setPriority(1);

		SubTaskEntity subTask_link = new SubTaskEntity();
		subTasks.add(subTask_link);

		subTask_link.setId(PrimaryKeyUtils.uniqueId());
		subTask_link.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask_link.setObjId(unit.getId());
		subTask_link.setObjName(unit.getRelateName());
		subTask_link.setObj(unit);
		subTask_link.setActionType(SubTaskDictConstants.ACTION_TYPE_LINK);
		subTask_link.setAsync(true);
		dfSubTaskConfig = definitionSubTaskConfigCache.getDfSubTaskConfigFromCache(subTask_link.getObjType(),
				subTask_link.getActionType());
		if (dfSubTaskConfig == null) {
			subTask_link.setTimeout(0);
		} else {
			subTask_link.setTimeout(dfSubTaskConfig.getTimeout());
		}
		subTask_link.setStatus(SubTaskDictConstants.STATUS_NOTRUN);
		String linkUrl = "/" + SysConstants.MGM_VERSION + "/services/link";
		subTask_link.setUrl(linkUrl);
		subTask_link.setMethodType(HttpClientUtils.METHOD_POST);
		subTask_link.setParam(getLinkParam(unit.getSubServ().getServ(), unit.getRelateId()));
		subTask_link.setPriority(2);
		return subTasks;
	}

	/**
	 * 构建单元重建所需参数
	 * 
	 * @param unit
	 *            单元对象
	 * @param paramMap
	 *            请求参数
	 * @return String 单元重建所需参数
	 */
	private String buildRebuildUnitParam(UnitEntity unit, Map<String, Object> paramMap) {
		JSONObject paramJson = new JSONObject();
		paramJson.put("nameOrID", unit.getRelateId());
		String strategy = (String) paramMap.get("strategy");
		if (DictConstants.STRATEGY_AUTO.equals(strategy)) {

		} else if (DictConstants.STRATEGY_MANUAL.equals(strategy)) {
			JSONArray candidateJsonArr = new JSONArray();
			paramJson.put("candidates", candidateJsonArr);
			String hostId = (String) paramMap.get("host");
			HostEntity host = hostDao.get(hostId);
			candidateJsonArr.add(host.getRelateId());
		}
		return paramJson.toJSONString();
	}

	/**
	 * 构建单元隔离任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildIsolateUnitTask(UnitEntity unit, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_ISOLATE);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_ISOLATE_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildIsolateUnitSubTasks(unit, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元隔离子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildIsolateUnitSubTasks(UnitEntity unit, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_ISOLATE);
		subTask.setAsync(false);
		subTask.setTimeout(HttpClientUtils.requestConfig.getSocketTimeout() + 10000);
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setPriority(1);
		return subTasks;
	}

	/**
	 * 构建单元回切任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param operateLog
	 *            操作日志对象
	 * @return 任务对象
	 */
	private TaskEntity buildRecoverUnitTask(UnitEntity unit, OperateLogEntity operateLog) {
		TaskEntity task = new TaskEntity();
		task.setId(PrimaryKeyUtils.uniqueId());
		task.setSite(unit.getSubServ().getServ().getOrder().getArea().getSite());
		task.setObjType(TaskDictConstants.OBJ_TYPE_UNIT);
		task.setObjId(unit.getId());
		task.setObjName(unit.getRelateName());
		task.setObj(unit);
		task.setActionType(TaskDictConstants.ACTION_TYPE_RECOVER);
		task.setOperateLog(operateLog);
		UserEntity user = getUser();
		String username = user.getUsername();
		task.setOwner(unit.getSubServ().getServ().getOrder().getOwner());
		task.setCreateUserLoginName(username);
		task.setStatus(TaskDictConstants.STATUS_RECOVER_RUNNING);
		task.setStartDateTime(operateLog.getCreateDateTime());

		List<SubTaskEntity> subTasks = buildRecoverUnitSubTasks(unit, task.getStartDateTime());
		task.setSubTasks(subTasks);
		return task;
	}

	/**
	 * 构建单元回切子任务
	 * 
	 * @param unit
	 *            单元对象
	 * @param date
	 *            任务开始时间
	 * @return 子任务集合
	 */
	private List<SubTaskEntity> buildRecoverUnitSubTasks(UnitEntity unit, Date date) {
		List<SubTaskEntity> subTasks = new ArrayList<SubTaskEntity>(1);
		SubTaskEntity subTask = new SubTaskEntity();
		subTasks.add(subTask);

		subTask.setId(PrimaryKeyUtils.uniqueId());
		subTask.setObjType(SubTaskDictConstants.OBJ_TYPE_UNIT);
		subTask.setObjId(unit.getId());
		subTask.setObjName(unit.getRelateName());
		subTask.setObj(unit);
		subTask.setActionType(SubTaskDictConstants.ACTION_TYPE_RECOVER);
		subTask.setAsync(false);
		subTask.setTimeout(HttpClientUtils.requestConfig.getSocketTimeout() + 10000);
		subTask.setStatus(SubTaskDictConstants.STATUS_RUNNING);
		subTask.setStartDateTime(date);
		subTask.setMethodType(HttpClientUtils.METHOD_POST);
		subTask.setPriority(1);
		return subTasks;
	}

	private List<SubServEntity> match(List<SubServEntity> subServs, String subServType) {
		List<SubServEntity> results = new ArrayList<>();
		for (SubServEntity subServ : subServs) {
			String dfSubServType = subServ.getSubOrder().getDefinitionSubServ().getName();
			if (subServType != null && !dfSubServType.equals(subServType)) {
				continue;
			}
			results.add(subServ);
		}
		return results;
	}
}
